package com.songminju.jsong_httpserver.http.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

import org.apache.log4j.Logger;

import com.songminju.jsong_httpserver.http.Cookie;
import com.songminju.jsong_httpserver.http.HttpResponse;

public class DefaultHttpResponse implements HttpResponse{
	
	private Writer out;
	private OutputStream outStream;
	Map<String,String> headers = new HashMap<>();
	private String httpVersion = "HTTP/1.1";
	private int state = 200;
	private String stateDesc = "OK";
	private boolean writeHeader = false;
	private boolean isEnd = false;
	private Logger logger = Logger.getLogger(this.getClass());
	
	public static DefaultHttpResponse createResponse(Socket socket) {
		DefaultHttpResponse res = new DefaultHttpResponse();
		try {
			res.outStream = socket.getOutputStream();
			res.out = new OutputStreamWriter(res.outStream);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		res.headers.put("Server", "JSong-HttpServer");
		res.headers.put("Transfer-Encoding", "chunked");
		res.headers.put("Content-Type", "text/plain");
		return res;
	}
	
	private void writeHeader() {
		logger.debug("write res header first line.");
		try {
			out.write(httpVersion+" "+state+" "+stateDesc+"\r\n");
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		headers.forEach(new BiConsumer<String,String>() {
			@Override
			public void accept(String t, String u) {
				try {
					logger.debug("write header:"+t+": "+u);
					out.write(t+": "+u);
					out.write("\r\n");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		try {
			out.write("\r\n");
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public HttpResponse print(String str) {
		return write(str.getBytes());
	}
	@Override
	public HttpResponse println(String str) {
		return print(str+"\n");
	}
	@Override
	public HttpResponse write(byte[] bytes) {
		if(bytes == null || bytes.length==0) {
			return this;
		}
		if(!writeHeader) {
			writeHeader = true;
			writeHeader();
		}
		try {
			out.write(Integer.toHexString(bytes.length) + "\r\n");
			out.flush();
			outStream.write(bytes);
			out.write("\r\n");
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			out.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return this;
	}
	@Override
	public HttpResponse state(int state) {
		this.state = state;
		return this;
	}
	@Override
	public HttpResponse header(String name, String value) {
		headers.put(name, value);
		return this;
	}
	@Override
	public HttpResponse cookie(Cookie cookie) {
		return null;
	}
	@Override
	public void end() {
		if(!isEnd) {
			isEnd = true;
			try {
				out.write("0\r\n\r\n");
				out.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	

}
